import { Component, OnInit } from "@angular/core";
import { SaleOrderSyncService } from "../../proxy/joy/erp/ufida/sales";
import { PurchaseRequisitionSyncService, PurchaseOrderSyncService } from "../../proxy/joy/erp/ufida/procurements";
import { AsnSyncService } from "../../proxy/joy/erp/ufida/asns";
import { ReceivementSyncService } from "../../proxy/joy/erp/ufida/receipt";
import { PlanOrderSyncService, ProductionOrderSyncService } from "../../proxy/joy/erp/ufida/production";
import { DocumentSyncService, AnalysisDto } from "../../proxy/joy/erp/ufida/core";
import { ListService, TrackByService } from "@abp/ng.core";
import { Observable, of, from, Subject, timer } from "rxjs";
import { finalize, catchError, concatMap, tap, takeUntil, switchMap } from "rxjs/operators";
import { NzModalService } from "ng-zorro-antd/modal";

interface AnalysisClientDto extends AnalysisDto {
  analyzefunc : (startDate?: string, endDate?: string) => Observable<AnalysisDto>;
  getIdsfunc: (startDate?: string, endDate?: string) => Observable<number[]>;
  batchSyncfunc: (ids: number[], startDate?: string, endDate?: string) => Observable<number>;
  getSyncedIdsfunc: (startDate?: string, endDate?: string) => Observable<number[]>;
  batchUpdatefunc: (ids: number[], startDate?: string, endDate?: string) => Observable<number>;
  progress?: {
    current: number;
    total: number;
    percentage: number;
  };
  daterange?: Date[];
}

@Component({
  selector: 'lib-document-sync',
  templateUrl: './document-sync.component.html',
  styleUrls: ['./document-sync.component.less'],
  providers: [ListService],
})
export class DocumentSyncComponent implements OnInit {
  
  models: AnalysisClientDto[] = [];
  selectedModels: AnalysisClientDto[] = [];
  totalCount: number = 0;

  serviceMap = {
    'Joy.Erp.BasicArchives.Sales.SaleOrder': this.saleOrderSyncService,
    'Joy.Erp.BasicArchives.Procurements.PurchaseRequisition': this.purchaseRequisitionSyncService,
    'Joy.Erp.BasicArchives.Procurements.PurchaseOrder': this.purchaseOrderSyncService,
    'Joy.Erp.BasicArchives.Asns.Asn': this.asnSyncService,
    'Joy.Erp.BasicArchives.Receipt.Receivement': this.receivementSyncService,
    'Joy.Erp.BasicArchives.Production.PlanOrder': this.planOrderSyncService,
    'Joy.Erp.BasicArchives.Production.ProductionOrder': this.productionOrderSyncService,
  };

  analyzingModels: Set<string> = new Set(); // 记录正在分析中的模型ID
  asyncModels: Set<string> = new Set(); // 记录正在同步中的模型ID
  updateModels: Set<string> = new Set(); // 记录正在更新中的模型ID
  cancelSyncSubject = new Subject<void>(); // 用于取消同步的Subject
  cancelUpdateSubject = new Subject<void>(); // 用于取消更新的Subject

  // 日期选择对话框相关属性
  isDatePickerVisible = false;
  selectedDateRange: Date[] = [];

  // 格式化日期为 YYYY-MM-DD 格式
  private formatDate(date: Date): string {
    const year = date.getFullYear();
    const month = String(date.getMonth() + 1).padStart(2, '0');
    const day = String(date.getDate()).padStart(2, '0');
    return `${year}-${month}-${day}`;
  }

  public get currentPage() {
    return this.listService.page + 1;
  }

  public set currentPage(page: number) {
    this.listService.page = Math.max(page - 1, 0);
  }

  public get maxResultCount() {
    return this.listService.maxResultCount;
  }

  public set maxResultCount(value: number) {
    this.listService.maxResultCount = value;
  }

  public get pageCount(): number {
    if (this.totalCount <= 0 || this.listService.maxResultCount <= 0) return 0;
    const pageCount = Math.floor(this.totalCount / this.listService.maxResultCount);
    return this.totalCount % this.listService.maxResultCount == 0 ? pageCount : pageCount + 1;
  }

  public get isAllSelected(): boolean {
    return (
      this.models.every(model => this.selectedModels.some(item => item.id === model.id)) &&
      !!this.models?.length
    );
  }
  public get indeterminate(): boolean {
    return (
      this.models.some(model => this.selectedModels.some(item => item.id == model.id)) &&
      !this.models.every(model => this.selectedModels.some(item => item.id == model.id))
    );
  }
  public get selectedCount(): number {
    return !!this.selectedModels.length ? this.selectedModels.length : 0;
  }

  constructor(    
    public readonly track: TrackByService,
    public readonly listService: ListService<AnalysisDto>,
    public documentSyncService: DocumentSyncService,
    public saleOrderSyncService: SaleOrderSyncService,
    public purchaseRequisitionSyncService: PurchaseRequisitionSyncService,
    public purchaseOrderSyncService: PurchaseOrderSyncService,
    public asnSyncService: AsnSyncService,
    public receivementSyncService: ReceivementSyncService,
    public planOrderSyncService: PlanOrderSyncService,
    public productionOrderSyncService: ProductionOrderSyncService,
    private modal: NzModalService,
  ) {}
  
  ngOnInit(): void {
    this.listService.maxResultCount = 100;
    this.loadModels();
  }


  loadModels() {
    this.documentSyncService.getEmpty().subscribe(result => {
      // 将AnalysisDto转换为AnalysisClientDto，并添加analyzefun
      this.models = result.items.map(item => ({
        ...item,
        analyzefunc: this.getAnalyzeFunction(item.id),
        getIdsfunc: this.getIdsFunction(item.id),
        batchSyncfunc: this.getBatchSyncFunction(item.id),
        getSyncedIdsfunc: this.getSyncedIdsFunction(item.id),
        batchUpdatefunc: this.getBatchUpdateFunction(item.id),
        daterange: [],
        progress: {
          current: 0,
          total: 0,
          percentage: 0
        }
      }));
      
      this.totalCount = result.totalCount;
    });
  }

  private getService(id: string) {
    return this.serviceMap[id] || null;
  }

  getAnalyzeFunction(id: string): (startDate?: string, endDate?: string) => Observable<AnalysisDto> {
    const service = this.getService(id);
    return service ? (startDate?: string, endDate?: string) => service.analyze(startDate, endDate) : () => of(null);
  }

  getIdsFunction(id: string): (startDate?: string, endDate?: string) => Observable<number[]> {
    const service = this.getService(id);
    return service ? (startDate?: string, endDate?: string) => service.getUnasyncIdsByStartAndEnd(startDate, endDate) : () => of([]);
  }

  getBatchSyncFunction(id: string): (ids: number[], startDate?: string, endDate?: string) => Observable<number> {
    const service = this.getService(id);
    return service ? (itemIds: number[], startDate?: string, endDate?: string) => service.createByIds(itemIds, startDate, endDate) : (itemIds: number[]) => of(0);
  }

  getSyncedIdsFunction(id: string): (startDate?: string, endDate?: string) => Observable<number[]> {
    const service = this.getService(id);
    return service ? (startDate?: string, endDate?: string) => service.getSyncedIdsByStartAndEnd(startDate, endDate) : () => of([]);
  }

  getBatchUpdateFunction(id: string): (ids: number[], startDate?: string, endDate?: string) => Observable<number> {
    const service = this.getService(id);
    return service ? (itemIds: number[], startDate?: string, endDate?: string) => service.updateByIds(itemIds, startDate, endDate) : (itemIds: number[]) => of(0);
  }

  renderModels(listResult) {    
    this.clearSelect();
    this.models = listResult.items;
    this.totalCount = listResult.totalCount;
  }

  isModelSelected(model: AnalysisClientDto): boolean {
    if (!this.selectedModels?.length) return false;
    if (this.selectedModels.length <= 0) return false;
    return !!this.selectedModels.find(x => x.id == model.id);
  }

  targetModelSelect(model: AnalysisClientDto): void {
    // 如果有操作正在进行，不执行选择操作
    if (this.isAnyOperationInProgress()) {
      return;
    }

    if (!this.selectedModels.some(item => item.id === model.id)) {
      this.selectedModels = [...this.selectedModels, model];
    } else {
      this.selectedModels = [...this.selectedModels.filter(item => item.id !== model.id)];
    }
  }

  targetAllSelect() {
    // 如果有操作正在进行，不执行选择操作
    if (this.isAnyOperationInProgress()) {
      return;
    }

    const allselected = this.models.every(model =>
      this.selectedModels.some(item => item.id === model.id)
    );

    if (allselected) {
      this.selectedModels = [
        ...this.selectedModels.filter(item => !this.models.some(model => model.id === item.id)),
      ];
    } else {
      this.selectedModels = [
        ...this.selectedModels,
        ...this.models.filter(model => !this.selectedModels.some(item => model.id === item.id)),
      ];
    }
  }

  clearSelect() {
    // 如果有操作正在进行，不执行选择操作
    if (this.isAnyOperationInProgress()) {
      return;
    }
    
    this.selectedModels = [];
  }

  analyze() {
    if (this.selectedModels.length === 0) {
      return;
    }

    // 显示日期选择对话框
    this.showDatePickerDialog();
  }

  // 显示日期选择对话框
  showDatePickerDialog() {
    // 检查选中的模型是否有起止日期，如果有则设置为默认值
    const modelWithDateRange = this.selectedModels.find(model => 
      model.daterange && model.daterange.length === 2
    );
    
    if (modelWithDateRange && modelWithDateRange.daterange) {
      this.selectedDateRange = [...modelWithDateRange.daterange];
    } else {
      this.selectedDateRange = [];
    }
    
    this.isDatePickerVisible = true;
  }

  // 处理日期选择确认
  onDatePickerOk() {
    if (this.selectedDateRange && this.selectedDateRange.length === 2) {
      // 将选择的日期范围应用到选中的模型
      this.selectedModels.forEach(model => {
        model.daterange = [...this.selectedDateRange];
      });
      
      // 执行分析
      this.executeAnalysis();
    }
    this.isDatePickerVisible = false;
  }

  // 处理日期选择取消
  onDatePickerCancel() {
    this.isDatePickerVisible = false;
  }

  // 执行分析的具体逻辑
  executeAnalysis() {
    // 根据order字段排序，然后使用RxJS串行处理，逐行执行分析
    const sortedModels = [...this.selectedModels].sort((a, b) => (a.order || 0) - (b.order || 0));
    from(sortedModels).pipe(
      concatMap(model => {
        if (!model.id) {
          return of(null);
        }
        
        // 设置当前模型为分析中状态
        this.analyzingModels.add(model.id);
        
        // 获取日期范围并格式化为字符串
        const startDate = model.daterange && model.daterange.length > 0 ? this.formatDate(model.daterange[0]) : undefined;
        const endDate = model.daterange && model.daterange.length > 1 ? this.formatDate(model.daterange[1]) : undefined;
        
        return model.analyzefunc(startDate, endDate).pipe(
          tap(result => {
            if (result) {
              const modelInList = this.models.find(m => m.id === model.id);
              
              if (modelInList) {
                // 复制AnalysisDto中的数量属性
                modelInList.u9Count = result.u9Count;
                modelInList.asyncCount = result.asyncCount;
                modelInList.unasyncCount = result.unasyncCount;
                modelInList.count = result.count;
                modelInList.selfCount = result.selfCount;
                modelInList.progress = {
                  current: 0,
                  total: 0,
                  percentage: 0
                };
              }
            }
          }),
          catchError(error => {
            console.error(`${model.id}:`, error);
            return of(null);
          }),
          finalize(() => {
            // 移除当前模型的分析中状态
            if (model.id) {
              this.analyzingModels.delete(model.id);
            }
          })
        );
      })
    ).subscribe();
  }

  sync() {
    if (this.selectedModels.length === 0) {
      return;
    }

    // 重置取消信号
    this.cancelSyncSubject = new Subject<void>();
    let isCancelled = false;

    // 根据order字段排序，然后使用RxJS串行处理，逐行执行同步
    const sortedModels = [...this.selectedModels].sort((a, b) => (a.order || 0) - (b.order || 0));
    
    // 创建一个可取消的同步流
    const syncStream = from(sortedModels).pipe(
      takeUntil(this.cancelSyncSubject),
      concatMap(model => {
        // 检查是否已取消
        if (isCancelled || !model.id) {
          return of(null);
        }
        
        // 检查 unasyncCount 是否有效
        const modelInList = this.models.find(m => m.id === model.id);
        if (!modelInList || !modelInList.unasyncCount || modelInList.unasyncCount <= 0) {
          // 如果没有未同步数据，跳过该模型
          return of(null);
        }
        
        // 设置当前模型为同步中状态
        this.asyncModels.add(model.id);
        
        // 重置进度
        if (modelInList) {
          modelInList.progress = {
            current: 0,
            total: 0,
            percentage: 0
          };
        }
        
        // 获取日期范围并格式化为字符串
        const startDate = model.daterange && model.daterange.length > 0 ? this.formatDate(model.daterange[0]) : undefined;
        const endDate = model.daterange && model.daterange.length > 1 ? this.formatDate(model.daterange[1]) : undefined;
        
        return model.getIdsfunc(startDate, endDate).pipe(
          takeUntil(this.cancelSyncSubject),
          concatMap(ids => {
            // 检查是否已取消
            if (isCancelled || !ids || ids.length === 0) {
              return of(null);
            }
            
            // 更新总数
            if (modelInList) {
              modelInList.progress.total = ids.length;
            }
            
            // 计算批次大小：根据数据量分段设置
            // 计算批次大小：总数量 / 600 向上取整，最小为1
            const batchSize = Math.max(1, Math.ceil(ids.length / 600));
            
            // 将ids数组按批次大小分组
            const batches: number[][] = [];
            for (let i = 0; i < ids.length; i += batchSize) {
              batches.push(ids.slice(i, i + batchSize));
            }
            
            // 批量执行同步
            return from(batches).pipe(
              takeUntil(this.cancelSyncSubject),
              concatMap(batch => {
                // 检查是否已取消
                if (isCancelled) {
                  return of(null);
                }
                
                // 使用switchMap包装同步操作，确保可以立即取消
                return timer(0).pipe(
                  takeUntil(this.cancelSyncSubject),
                  switchMap(() => {
                    if (isCancelled) {
                      return of(null);
                    }
                    
                    return model.batchSyncfunc(batch, startDate, endDate).pipe(
                      takeUntil(this.cancelSyncSubject),
                      tap(successCount => {
                        // 检查是否已取消
                        if (isCancelled) {
                          return;
                        }
                        
                        // 更新进度
                        if (modelInList && modelInList.progress) {
                          modelInList.progress.current += batch.length;
                          modelInList.progress.percentage = Math.round((modelInList.progress.current / modelInList.progress.total) * 100);
                        }
                        
                        // 根据同步结果更新计数
                        if (modelInList && successCount > 0) {
                          // 成功时：asyncCount +successCount, unasyncCount -successCount
                          modelInList.asyncCount = (modelInList.asyncCount || 0) + successCount;
                          modelInList.unasyncCount = Math.max(0, (modelInList.unasyncCount || 0) - successCount);
                          modelInList.count = Math.max(0, (modelInList.count || 0) + successCount);
                        }
                      }),
                      catchError(error => {
                        console.error(`${model.id} - Batch:`, error);
                        // 检查是否已取消
                        if (!isCancelled && modelInList && modelInList.progress) {
                          modelInList.progress.current += batch.length;
                          modelInList.progress.percentage = Math.round((modelInList.progress.current / modelInList.progress.total) * 100);
                        }
                        return of(0);
                      })
                    );
                  })
                );
              })
            );
          }),
          catchError(error => {
            console.error(`${model.id}:`, error);
            return of(null);
          }),
          finalize(() => {
            // 移除当前模型的同步中状态
            if (model.id) {
              this.asyncModels.delete(model.id);
            }
          })
        );
      })
    );

    // 订阅同步流
    syncStream.subscribe();

    // 监听取消信号
    this.cancelSyncSubject.subscribe(() => {
      isCancelled = true;
    });
  }

  isModelAnalyzing(modelId: string): boolean {
    return this.analyzingModels.has(modelId);
  }

  isModelSync(modelId: string): boolean {
    return this.asyncModels.has(modelId);
  }

  getModelProgress(modelId: string): { current: number; total: number; percentage: number } {
    const model = this.models.find(m => m.id === modelId);
    return model?.progress || { current: 0, total: 0, percentage: 0 };
  }

  hasValidUnasyncCount(): boolean {
    return this.selectedModels.some(model => {
      const modelInList = this.models.find(m => m.id === model.id);
      return modelInList && modelInList.unasyncCount && modelInList.unasyncCount > 0;
    });
  }

  hasValidSyncedCount(): boolean {
    return this.selectedModels.some(model => {
      const modelInList = this.models.find(m => m.id === model.id);
      return modelInList && modelInList.asyncCount && modelInList.asyncCount > 0;
    });
  }

  update() {
    if (this.selectedModels.length === 0) {
      return;
    }

    // 重置取消信号
    this.cancelUpdateSubject = new Subject<void>();
    let isCancelled = false;

    // 根据order字段排序，然后使用RxJS串行处理，逐行执行更新
    const sortedModels = [...this.selectedModels].sort((a, b) => (a.order || 0) - (b.order || 0));
    
    // 创建一个可取消的更新流
    const updateStream = from(sortedModels).pipe(
      takeUntil(this.cancelUpdateSubject),
      concatMap(model => {
        // 检查是否已取消
        if (isCancelled || !model.id) {
          return of(null);
        }
        
        // 检查 asyncCount 是否有效
        const modelInList = this.models.find(m => m.id === model.id);
        if (!modelInList || !modelInList.asyncCount || modelInList.asyncCount <= 0) {
          // 如果没有已同步数据，跳过该模型
          return of(null);
        }
        
        // 设置当前模型为更新中状态
        this.updateModels.add(model.id);
        
        // 重置进度和pmc数量
        if (modelInList) {
          modelInList.progress = {
            current: 0,
            total: 0,
            percentage: 0
          };
          // 暂存原始pmc数量，用于出错时恢复
          const originalAsyncCount = modelInList.count;
          // 将已同步数量设置为0
          modelInList.count = 0;
        }
        
        // 获取日期范围并格式化为字符串
        const startDate = model.daterange && model.daterange.length > 0 ? this.formatDate(model.daterange[0]) : undefined;
        const endDate = model.daterange && model.daterange.length > 1 ? this.formatDate(model.daterange[1]) : undefined;
        
        return model.getSyncedIdsfunc(startDate, endDate).pipe(
          takeUntil(this.cancelUpdateSubject),
          concatMap(ids => {
            // 检查是否已取消
            if (isCancelled || !ids || ids.length === 0) {
              return of(null);
            }
            
            // 更新总数
            if (modelInList) {
              modelInList.progress.total = ids.length;
            }
            
            // 计算批次大小：总数量 / 600 向上取整，最小为1
            const batchSize = Math.max(1, Math.ceil(ids.length / 600));
            
            // 将ids数组按批次大小分组
            const batches: number[][] = [];
            for (let i = 0; i < ids.length; i += batchSize) {
              batches.push(ids.slice(i, i + batchSize));
            }
            
            // 批量执行更新
            return from(batches).pipe(
              takeUntil(this.cancelUpdateSubject),
              concatMap(batch => {
                // 检查是否已取消
                if (isCancelled) {
                  return of(null);
                }
                
                // 使用switchMap包装更新操作，确保可以立即取消
                return timer(0).pipe(
                  takeUntil(this.cancelUpdateSubject),
                  switchMap(() => {
                    if (isCancelled) {
                      return of(null);
                    }
                    
                    return model.batchUpdatefunc(batch, startDate, endDate).pipe(
                      takeUntil(this.cancelUpdateSubject),
                      tap(successCount => {
                        // 检查是否已取消
                        if (isCancelled) {
                          return;
                        }
                        
                        // 更新进度
                        if (modelInList && modelInList.progress) {
                          modelInList.progress.current += batch.length;
                          modelInList.progress.percentage = Math.round((modelInList.progress.current / modelInList.progress.total) * 100);
                        }
                        
                        // 根据更新结果更新计数：count逐步增加
                        if (modelInList && successCount > 0) {
                          modelInList.count = (modelInList.count || 0) + successCount;
                        }
                      }),
                      catchError(error => {
                        console.error(`${model.id} - Update Batch:`, error);
                        // 检查是否已取消
                        if (!isCancelled && modelInList && modelInList.progress) {
                          modelInList.progress.current += batch.length;
                          modelInList.progress.percentage = Math.round((modelInList.progress.current / modelInList.progress.total) * 100);
                        }
                        return of(0);
                      })
                    );
                  })
                );
              })
            );
          }),
          catchError(error => {
            console.error(`${model.id}:`, error);
            return of(null);
          }),
          finalize(() => {
            // 移除当前模型的更新中状态
            if (model.id) {
              this.updateModels.delete(model.id);
            }
          })
        );
      })
    );

    // 订阅更新流
    updateStream.subscribe();

    // 监听取消信号
    this.cancelUpdateSubject.subscribe(() => {
      isCancelled = true;
    });
  }

  cancelSync(): void {
    // 立即发送取消信号
    this.cancelSyncSubject.next();
    this.cancelSyncSubject.complete();
    
    // 清除所有同步状态
    this.asyncModels.clear();
    
    // 重置所有模型的进度
    this.models.forEach(model => {
      if (model.progress) {
        model.progress.current = 0;
        model.progress.total = 0;
        model.progress.percentage = 0;
      }
    });
    
    // 重置取消信号，为下次同步做准备
    this.cancelSyncSubject = new Subject<void>();
  }

  cancelUpdate(): void {
    // 立即发送取消信号
    this.cancelUpdateSubject.next();
    this.cancelUpdateSubject.complete();
    
    // 清除所有更新状态
    this.updateModels.clear();
    
    // 重置所有模型的进度
    this.models.forEach(model => {
      if (model.progress) {
        model.progress.current = 0;
        model.progress.total = 0;
        model.progress.percentage = 0;
      }
    });
    
    // 重置取消信号，为下次更新做准备
    this.cancelUpdateSubject = new Subject<void>();
  }

  isSyncInProgress(): boolean {
    return this.asyncModels.size > 0;
  }

  isUpdateInProgress(): boolean {
    return this.updateModels.size > 0;
  }

  isModelUpdating(modelId: string): boolean {
    return this.updateModels.has(modelId);
  }

  isAnyOperationInProgress(): boolean {
    return this.analyzingModels.size > 0 || this.asyncModels.size > 0 || this.updateModels.size > 0;
  }

  progressFormat = (percent: number): string => {
    return `${percent}%`;
  }
}